package drone.basis.util ;

import java.awt.Color ;
import java.awt.Font ;
import java.awt.Graphics ;
import java.awt.image.BufferedImage ;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
import java.util.Random ;

import javax.imageio.ImageIO ;
import javax.imageio.stream.ImageOutputStream ;

public class CodeUtil
{

	public String createCode (
			int disturbType ,
			int fontSize ,
			ByteArrayOutputStream bos ,
			int width ,
			int height ,
			int codeLength
	)
	{
		BufferedImage bImg = new BufferedImage ( width , height , BufferedImage.TYPE_INT_RGB ) ;
		Graphics g = bImg.getGraphics ( ) ;
		Random random = new Random ( ) ;
		if ( fontSize >= height )
		{
			fontSize = height - 1 ;
		}
		drawOutline ( g , width , height ) ;
		switch ( disturbType )
		{
			case 1 :
				drawSimpleDisturb ( g , random , width , height ) ;
				break ;
			case 2 :
				drawDisturb ( g , random , width , height ) ;
				break ;
			default :
				break ;
		}
		String code = drawCode ( g , random , codeLength , width , height , fontSize ) ;
		g.dispose ( ) ;
		try
		{
			ImageOutputStream imOut = ImageIO.createImageOutputStream ( bos ) ;
			ImageIO.write ( bImg , "JPEG" , imOut ) ;
			imOut.close ( ) ;
			imOut.reset ( ) ;
		} catch ( IOException e )
		{
			e.printStackTrace ( ) ;
		}
		return code ;
	}

	private static void drawOutline (
			Graphics g ,
			int width ,
			int height
	)
	{
		g.setColor ( Color.white ) ;
		g.fillRect ( 0 , 0 , width , height ) ;
		g.setColor ( Color.BLACK ) ;
		g.drawRect ( 0 , 0 , width - 1 , height - 1 ) ;
	}

	private static void drawDisturb (
			Graphics g ,
			Random random ,
			int width ,
			int height
	)
	{
		int x , y , x1 , y1 ;
		for ( int i = 0 ; i < width ; i ++ )
		{
			x = random.nextInt ( width ) ;
			y = random.nextInt ( height ) ;
			x1 = random.nextInt ( 12 ) ;
			y1 = random.nextInt ( 12 ) ;
			g.setColor ( getRandomColor ( random , 120 , 255 ) ) ;
			g.drawLine ( x , y , x + x1 , y + y1 ) ;
			g.fillArc ( x , y , x1 , y1 , random.nextInt ( 360 ) , random.nextInt ( 360 ) ) ;
		}
	}

	private static void drawSimpleDisturb (
			Graphics g ,
			Random random ,
			int width ,
			int height
	)
	{
		g.setColor ( getRandomColor ( random , 160 , 200 ) ) ;
		for ( int i = 0 ; i < 155 ; i ++ )
		{
			int x = random.nextInt ( width ) ;
			int y = random.nextInt ( height ) ;
			int xl = random.nextInt ( 12 ) ;
			int yl = random.nextInt ( 12 ) ;
			g.drawLine ( x , y , x + xl , y + yl ) ;
		}
	}

	private static Color getRandomColor (
			Random random ,
			int pMin ,
			int pMax
	)
	{
		pMax = ( Math.abs ( pMax ) > 255 ? 255 : Math.abs ( pMax ) ) ;
		pMin = ( Math.abs ( pMin ) > 255 ? 255 : Math.abs ( pMin ) ) ;
		int r = pMin + random.nextInt ( Math.abs ( pMax - pMin ) ) ;
		int g = pMin + random.nextInt ( Math.abs ( pMax - pMin ) ) ;
		int b = pMin + random.nextInt ( Math.abs ( pMax - pMin ) ) ;
		return new Color ( r , g , b ) ;
	}

	private static String drawCode (
			Graphics g ,
			Random random ,
			int codeLength ,
			int width ,
			int height ,
			int fontSize
	)
	{
		Font font1 = new Font ( "Verdana" , Font.BOLD , fontSize ) ;
		Font font2 = new Font ( "serif" , Font.BOLD , fontSize ) ;
		StringBuffer sb = new StringBuffer ( ) ;
		int x , y ;
		for ( int i = 0 ; i < codeLength ; i ++ )
		{
			x = ( width / codeLength - 1 ) * i + random.nextInt ( width / ( codeLength * 2 ) ) ;
			y = random.nextInt ( height - fontSize ) + fontSize ;
			sb.append ( random.nextInt ( 10 ) ) ;
			g.setColor ( getRandomColor ( random , 70 , 150 ) ) ;
			if ( sb.substring ( i ).getBytes ( ).length > 1 )
				g.setFont ( font2 ) ;
			else
				g.setFont ( font1 ) ;
			g.drawString ( sb.substring ( i ) , x , y ) ;
		}
		return sb.toString ( ) ;
	}
}
